package com.rc.evcharger.common.base.yl;


import com.rc.evcharger.common.annotation.ByteLength;
import com.rc.evcharger.common.base.TResponse;
import com.rc.evcharger.common.utils.DataUtil;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;

public abstract class BaseYlType implements BaseYlDataType {
    int length;
    protected int MSTA_PWD_LENGTH = 9;  //起始域+长度域+信息域+序列号+控制码长度

    protected int JN_MSTA_PWD_LENGTH = 14;  //起始域+长度域+信息域+序列号+控制码长度

    @Override
    public Object getValue(String dataStr) {
        return null;
    }

    /***
     * 通过反射构造帧格式数据
     */
    @Override
    public String createFrame() {
        StringBuffer sb = new StringBuffer();

        Field[] fields = this.getClass().getDeclaredFields();


        try {

            //构造停止指令
            //if (this.getClass().getSimpleName().equals("ChargingCommandResp")) {
            //    Field terminalId = this.getClass().getField("terminalId");
            //    createFrame(sb, terminalId);
            //}

            for (Field field : fields) {
                field.setAccessible(true);
                createFrame(sb, field);

                //订单号后跟桩编号
                //if (field.getName().equals("orderNum")) {
                //    Field terminalId = this.getClass().getField("terminalId");
                //    createFrame(sb, terminalId);
                //}
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        String value = sb.toString().trim();


        String simpleName = this.getClass().getSimpleName();
        if (simpleName.substring(0, 2).equals("Jn")) {
            //长度+16
            this.length = value.split(SPLIT).length + JN_MSTA_PWD_LENGTH;
        } else {
            //长度+9
            this.length = value.split(SPLIT).length + MSTA_PWD_LENGTH;
        }
        return value;
    }

    protected void createFrame(StringBuffer sb, Field field) throws Exception {
        if (field.getName().equals("length") || field.get(this) == null) {
            return;
        }
        //如果子类执行该自定义方法就跳过下页面，进行某个字段自定义构造帧格式数据
        if (customField(field, sb)) {
            return;
        }
        if (field.getType().equals(String.class)) {
            String value = field.get(this).toString();
            if (value.length() < 2)
                sb.append("0");
            sb.append(value).append(SPLIT);
        }
        if (field.getType().equals(BigDecimal.class)) {
            ByteLength bl = field.getAnnotation(ByteLength.class);
            BigDecimal value = (BigDecimal) field.get(this);
            //根据倍率扩大数值
            value = value.multiply(new BigDecimal(Math.pow(10, bl.decimal())));
            //value=value.setScale(bl.decimal(), BigDecimal.ROUND_DOWN);
            String str = String.valueOf(value.intValue());
            //不足长度高位补0
            int len = bl.length() * 2 - str.length();
            for (int i = 0; i < len; i++) {
                str = "0" + str;
            }
            //将数据进行低位在前高位在后    1234  34 21
            for (int i = bl.length(); i > 0; i--) {
                sb.append(str.substring((i - 1) * 2, i * 2)).append(SPLIT);
            }
        }
        if (field.getType().equals(String[].class)) {
            String[] value = (String[]) field.get(this);
            for (String str : value) {
                sb.append(str).append(SPLIT);
            }
        }
        if (field.getType().equals(Integer.class)) {
            Integer value = (Integer) field.get(this);
            String str = Integer.toHexString(value).toUpperCase();
            if (str.length() < 2) {
                sb.append("0");
            }
            sb.append(str).append(SPLIT);
        }
    }


    /**
     * 构建枪号
     *
     * @param gunNum
     * @return
     */
    public String frameGunNum(String gunNum) {
        if (gunNum.length() < 2) {
            return "0" + gunNum;
        }
        return gunNum;
    }

    /**
     * 10进制转16进制报文
     *
     * @param account 金额
     * @param decimal 精度
     * @return
     */
    public String frameHexToDecimal(BigDecimal account, int decimal) {
        String s = String.valueOf(account.setScale(decimal, RoundingMode.CEILING.HALF_UP));
        String strAccount = s.replace(".", "");

        int hexValue = Integer.parseInt(strAccount, 16);
        //补0
        String format = String.format("%08d", Integer.valueOf(hexValue));
        String accountReport = "";
        for (int i = 0; i < 4; i++) {
            accountReport = format.substring(i * 2, i * 2 + 2) + " " + accountReport;
        }
        return accountReport.trim();
    }


    /**
     * 将数据长度变成16进制
     */
    @Override
    public String getLength() {
        String hex = Integer.toHexString(length);
        //if (hex.length() == 1) {
        //    hex = "0" + hex;
        //}
        String[] ss = {"0000", "000", "00", "0"};
        hex = ss[hex.length()] + hex;
        hex = hex.toUpperCase();
        hex = DataUtil.turnValue(hex);

        return hex.substring(2) + SPLIT + hex.substring(0, 2);
    }

    /**
     * @return 返回帧格式
     * <p>
     * 智充专用
     */
    protected String frameOrderNum(String orderNum) {
        char[] c = orderNum.toCharArray();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < c.length; i = i + 2) {
            sb.append(c[i]).append(c[i + 1]).append(DataUtil.SPLIT);
        }
        sb.append("00");
        return sb.toString().trim();
    }


    /**
     * 如果某些字段转变数据的方式不一样可以实现这方法
     *
     * @param field
     * @param sb
     * @return
     */
    public abstract boolean customField(Field field, StringBuffer sb);


    public static void main(String[] args) {
        TResponse tResponse = new TResponse(1, "");
        String simpleName = tResponse.getClass().getSimpleName();
        System.out.println(simpleName);
        if (simpleName.substring(0, 2).equals("TR")) {
            System.out.println();
        }
    }
}
